package com.kehutong.charge.util;

import java.util.ArrayList;
import java.util.Collections;

/**
 * @program: kht
 * @description: 人民币转换
 * @author: joneron
 * @create: 2021/6/4
 **/
public class MoneyUtil {

    /**
     * 单位进位，中文默认为4位即（万、亿）
     */
    public static  int UNIT_STEP = 4;

    /** 单位 */
    //public static String[] CN_UNITS = new String[] {"个", "十", "百", "千", "万", "十","百", "千", "亿", "十", "百", "千", "万" };

    /** 单位 */
    public static String[] CN_UNITS = new String[] {"圆", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟"};

    /*** 汉字 */
    public static String[] CN_CHARS = new String[] {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

    /**
     * 将阿拉伯数字转换为中文数字123=》
     * @param srcNum
     * @return
     */
    public static String getCNNum(int srcNum) {
        String desCNNum = "";

        if (srcNum <= 0)
            desCNNum = "零";
        else {
            int singleDigit;
            while (srcNum > 0) {
                singleDigit = srcNum % 10;
                desCNNum = String.valueOf(CN_CHARS[singleDigit]) + desCNNum;
                srcNum /= 10;
            }
        }

        return desCNNum;
    }

    /**
     * 数值转换为中文字符串 如2转化为贰
     */
    public static String cvt(long num) {
        return cvt(num, false);
    }

    /**
     * 数值转换为中文字符串(口语化)
     *
     * @param num  需要转换的数值
     * @param isColloquial 是否口语化。例如12转换为'十二'而不是'一十二'。
     * @return
     */
    public static String cvt(String num, boolean isColloquial) {
        int integer, decimal;
        StringBuffer strs = new StringBuffer(32);
        String[] splitNum = num.split("\\.");
        integer = Integer.parseInt(splitNum[0]);    //整数部分
        decimal = Integer.parseInt(splitNum[1]);    //小数部分
        String[] result_1 =convert(integer, isColloquial);
        for (String str1 : result_1)
            strs.append(str1);
        if(decimal==0){//小数部分为0时
            return strs.toString();
        }else{
            String result_2 =getCNNum(decimal);  //例如5.32，小数部分展示三二，而不是三十二
            //strs.append("点");
            strs.append(result_2);
            return strs.toString();
        }
    }

    /*
     * 对于int,long类型的数据处理
     */
    public static String cvt(long num, boolean isColloquial) {
        String[] result = convert(num, isColloquial);
        StringBuffer strs = new StringBuffer(32);
        for (String str : result) {
            strs.append(str);
        }
        return strs.toString();
    }

    /**
     * 将数值转换为中文
     * @param num 需要转换的数值
     * @param isColloquial 是否口语化。例如12转换为'十二'而不是'一十二'。
     * @return
     */
    public static String[] convert(long num, boolean isColloquial) {
        if (num < 10) {// 10以下直接返回对应汉字
            return new String[] { CN_CHARS[(int) num] };// ASCII2int
        }

        char[] chars = String.valueOf(num).toCharArray();
        if (chars.length > CN_UNITS.length) {// 超过单位表示范围的返回空
            return new String[] {};
        }

        boolean isLastUnitStep = false;// 记录上次单位进位
        ArrayList<String> cnchars = new ArrayList<String>(chars.length * 2);// 创建数组，将数字填入单位对应的位置
        for (int pos = chars.length - 1; pos >= 0; pos--) {// 从低位向高位循环
            char ch = chars[pos];
            String cnChar = CN_CHARS[ch - '0'];// ascii2int 汉字
            int unitPos = chars.length - pos - 1;// 对应的单位坐标
            String cnUnit = CN_UNITS[unitPos];// 单位
            boolean isZero = (ch == '0');// 是否为0
            boolean isZeroLow = (pos + 1 < chars.length && chars[pos + 1] == '0');// 是否低位为0

            boolean isUnitStep = (unitPos >= UNIT_STEP && (unitPos % UNIT_STEP == 0));// 当前位是否需要单位进位

            if (isUnitStep && isLastUnitStep) {// 去除相邻的上一个单位进位
                int size = cnchars.size();
                cnchars.remove(size - 1);
                if (!CN_CHARS[0].equals(cnchars.get(size - 2))) {// 补0
                    cnchars.add(CN_CHARS[0]);
                }
            }

            if (isUnitStep || !isZero) {// 单位进位(万、亿)，或者非0时加上单位
                cnchars.add(cnUnit);
                isLastUnitStep = isUnitStep;
            }
            if (isZero && (isZeroLow || isUnitStep)) {// 当前位为0低位为0，或者当前位为0并且为单位进位时进行省略
                continue;
            }
            cnchars.add(cnChar);
            isLastUnitStep = false;
        }

        Collections.reverse(cnchars);
        // 清除最后一位的0
        int chSize = cnchars.size();
        String chEnd = cnchars.get(chSize - 1);
        if (CN_CHARS[0].equals(chEnd) || CN_UNITS[0].equals(chEnd)) {
            cnchars.remove(chSize - 1);
        }

        // 口语化处理
        if (isColloquial) {
            String chFirst = cnchars.get(0);
            String chSecond = cnchars.get(1);
            if (chFirst.equals(CN_CHARS[1]) && chSecond.startsWith(CN_UNITS[1])) {// 是否以'一'开头，紧跟'十'
                cnchars.remove(0);
            }
        }
        return cnchars.toArray(new String[] {});
    }

    public static void main(String[] args) {
        MoneyUtil temp = new MoneyUtil();
        String i ="40.3";
        int t = 2234;
        double j = 221.83;
        System.out.println(temp.cvt(i,true));//四十点三
        System.out.println(temp.cvt(t,true));//二千二百三十四
        System.out.println(temp.cvt(""+j,true));//贰百贰十壹点贰叁

        System.out.println("====="+showMoney(j));
    }

    public static String showMoney(double amount){
        boolean negative = false;
        if (amount < 0.0D){
            negative = true;
            amount *= -1D;
        }

        long temp = Math.round(amount * 100D);
        int numFen = (int)(temp % 10L);
        temp /= 10L;
        int numJiao = (int)(temp % 10L);
        temp /= 10L;
        int parts[] = new int[20];
        int numParts = 0;
        for (int i = 0; temp != 0L; i++){
            int part = (int)(temp % 10000L);
            parts[i] = part;
            numParts++;
            temp /= 10000L;
        }

        boolean beforeWanIsZero = true;
        String chineseStr = "";
        for (int i = 0; i < numParts; i++){
            String partChinese = partTranslate(parts[i]);
            if (i % 2 == 0) {
                if ("".equals(partChinese))
                    beforeWanIsZero = true;
                else
                    beforeWanIsZero = false;
            }
            if (i != 0)
                if (i % 2 == 0)
                    chineseStr = (new StringBuilder("亿")).append(chineseStr).toString();
                else

                if ("".equals(partChinese) && !beforeWanIsZero){
                    chineseStr = (new StringBuilder("零")).append(chineseStr).toString();

                } else{
                    if (parts[i - 1] < 1000 && parts[i - 1] > 0)

                        chineseStr = (new StringBuilder("零")).append(chineseStr).toString();

                    chineseStr = (new StringBuilder("万")).append(chineseStr).toString();

                }

            chineseStr = (new StringBuilder(String.valueOf(partChinese))).append(chineseStr).toString();

        }

        if ("".equals(chineseStr))
            chineseStr = CN_CHARS[0];
        else

        if (negative)

            chineseStr = (new StringBuilder("负")).append(chineseStr).toString();

        chineseStr = (new StringBuilder(String.valueOf(chineseStr))).append("元").toString();

        if (numFen == 0 && numJiao == 0)
            chineseStr = (new StringBuilder(String.valueOf(chineseStr))).append("整").toString();
        else

        if (numFen == 0)
            chineseStr = (new StringBuilder(String.valueOf(chineseStr))).append(CN_CHARS[numJiao]).append("角").toString();
        else

        if (numJiao == 0)
            chineseStr = (new StringBuilder(String.valueOf(chineseStr))).append("零角").append(CN_CHARS[numFen]).append("分").toString();
        else
            chineseStr = (new StringBuilder(String.valueOf(chineseStr))).append( CN_CHARS[numJiao]).append("角").append(CN_CHARS[numFen]).append("分").toString();

        return chineseStr;

    }

    private static String partTranslate(int amountPart){
        if (amountPart < 0 || amountPart > 0x5f5e100)
            throw new IllegalArgumentException("参数必须是大于等于 0，小于 100000000 的整数！");
        String units[] = {"", "拾", "佰", "仟"};

        int temp = amountPart;
        String amountStr = (new Integer(amountPart)).toString();
        int amountStrLength = amountStr.length();
        boolean lastIsZero = true;
        String chineseStr = "";

        for (int i = 0; i < amountStrLength; i++){
            if (temp == 0)
                break;
            int digit = temp % 10;
            if (digit == 0){
                if (!lastIsZero)
                    chineseStr = (new StringBuilder("零")).append(chineseStr).toString();
                lastIsZero = true;
            } else{
                chineseStr = (new StringBuilder(String.valueOf(CN_CHARS[digit]))).append(units[i]).append(chineseStr).toString();
                lastIsZero = false;
            }
            temp /= 10;
        }

        return chineseStr;

    }

}
